package com.koron.plan.web.patrolplan.service.impl;

import com.koron.bean.system.staff.vo.EamUser;
import com.koron.common.core.config.ThreadLocalContext;
import com.koron.common.core.util.CodeTools;
import com.koron.common.core.util.OrgCacheUtils;
import com.koron.plan.config.Constants;
import com.koron.plan.web.common.CommonUtils;
import com.koron.plan.web.patrolplan.bean.convertor.PatrolPlanConvertor;
import com.koron.plan.web.patrolplan.bean.entity.PatrolPlanEnvBean;
import com.koron.plan.web.patrolplan.bean.entity.PatrolPlanItemBean;
import com.koron.plan.web.patrolplan.bean.entity.PatrolPlanPointBean;
import com.koron.plan.web.patrolplan.bean.entity.PatrolPlanRecordBean;
import com.koron.plan.web.patrolplan.bean.query.PatrolPointQuery;
import com.koron.plan.web.patrolplan.bean.vo.PatrolPlanEquipVO;
import com.koron.plan.web.patrolplan.bean.vo.PatrolPlanPointDetailVO;
import com.koron.plan.web.patrolplan.bean.vo.PatrolPlanPointVO;
import com.koron.plan.web.patrolplan.mapper.PatrolPlanPointMapper;
import com.koron.plan.web.patrolplan.service.*;
import org.apache.commons.lang3.StringUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.koron.ebs.mybatis.TaskAnnotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author twcao
 * @title: PatrolPlanPointServiceImpl
 * @projectName GDH_EAM_V2
 * @description: 巡视点service
 * @date 2021/10/279:07
 */
@Service
public class PatrolPlanPointServiceImpl implements PatrolPlanPointService {

    @Autowired
    private PatrolPlanEquipmentService equipmentService;

    @Autowired
    private PatrolPlanItemService itemService;

    @Autowired
    private PatrolPlanRecordService recordService;

    @Autowired
    private PatrolPlanEnvService envService;

    @Autowired
    private PatrolPlanConvertor convertor;

    @Autowired
    private OrgCacheUtils orgUtils;

    @Autowired
    private HttpServletRequest httpServletRequest;
    /**
     * 通过ID查询单条数据
     * @param factory 会话
     * @param pointId 巡视点id
     * @return 实例对象
     */
    @Override
    @TaskAnnotation("queryById")
    public PatrolPlanPointDetailVO queryById(SessionFactory factory, String pointId) {
        PatrolPlanPointMapper mapper = factory.getMapper(PatrolPlanPointMapper.class);
        PatrolPlanPointDetailVO detail = mapper.queryById(pointId);
        detail.setEquips(mapper.select_equip_list(pointId,httpServletRequest.getHeader("Language")));
        return detail;
    }

    @Override
    @TaskAnnotation("queryBatchById")
    public List<PatrolPlanPointDetailVO> queryBatchById(SessionFactory factory, List<String> pointIds) {
        if(CollectionUtils.isEmpty(pointIds)) {
            return new ArrayList<>();
        }
        PatrolPlanPointMapper mapper = factory.getMapper(PatrolPlanPointMapper.class);
        List<PatrolPlanPointDetailVO> details = mapper.queryBatchById(pointIds);
        details.stream().forEach(patrolPlanPointDetailVO -> {
            patrolPlanPointDetailVO.setEquips(mapper.select_equip_list(patrolPlanPointDetailVO.getId(),httpServletRequest.getHeader("Language")));
        });
        return details;
    }

    /**
     * 查询多条数据
     * @param factory 会话
     * @param query   查询条件(delete_flag = true 可查询逻辑删除的数据)
     * @return 对象列表
     */
    @Override
    @TaskAnnotation("queryList")
    public List<PatrolPlanPointVO> queryList(SessionFactory factory, PatrolPointQuery query) {
        PatrolPlanPointMapper mapper = factory.getMapper(PatrolPlanPointMapper.class);
        List<PatrolPlanPointVO> points = mapper.queryList(query);
        return points;
    }

    /**
     * 新增/编辑数据
     * @param factory
     * @param detail  实例对象详情
     * @return 实例对象
     */
    @Override
    @TaskAnnotation("saveOrUpdate")
    public PatrolPlanPointDetailVO saveOrUpdate(SessionFactory factory, PatrolPlanPointDetailVO detail) {
        // 1、巡视点
        saveOrUpdate(factory, (PatrolPlanPointBean) detail);
        String pointId = detail.getId();
        List<PatrolPlanEnvBean> envs = detail.getEnvs();
        if(!CollectionUtils.isEmpty(envs)) {
            CommonUtils.update(envs);
            CommonUtils.sorted(envs);
            envs.stream().forEach(env -> {
                env.setId(StringUtils.isBlank(env.getId()) ? CodeTools.getCode32() : env.getId());
                env.setPatrolPointId(pointId);
            });
        }
        // 巡视设备
        List<PatrolPlanEquipVO> equips = detail.getEquips();
        Assert.isTrue(!CollectionUtils.isEmpty(equips), "巡视设备必选");
        CommonUtils.update(equips);
        CommonUtils.sorted(equips);
        equips.stream().forEach(equip -> {
            equip.setId(StringUtils.isBlank(equip.getId()) ? CodeTools.getCode32() : equip.getId());
            equip.setPatrolPointId(pointId);
            List<PatrolPlanItemBean> items = equip.getItems();
            if(!CollectionUtils.isEmpty(items)) {
                items.stream().forEach(item -> {
                    item.setId(StringUtils.isBlank(item.getId()) ? CodeTools.getCode32() : item.getId());
                    item.setPatrolEquipmentId(equip.getId());
                    item.setPatrolPointId(pointId);
                });
            }
            List<PatrolPlanRecordBean> records = equip.getRecords();
            if(!CollectionUtils.isEmpty(records)) {
                records.stream().forEach(record -> {
                    record.setId(StringUtils.isBlank(record.getId()) ? CodeTools.getCode32() : record.getId());
                    record.setPatrolEquipmentId(equip.getId());
                    record.setPatrolPointId(pointId);
                });
            }
        });
        // 检查项
        List<PatrolPlanItemBean> items = equips.stream().flatMap(equip -> equip.getItems().stream()).collect(Collectors.toList());
        // 记录项
        List<PatrolPlanRecordBean> records = equips.stream().flatMap(equip -> equip.getRecords().stream()).collect(Collectors.toList());
        // 2.1、环境
        envService.deleteByPointId(factory, pointId);
        envService.saveOrUpdate(factory, envs);
        // 2.2、设备
        equipmentService.deleteByPointId(factory, pointId);
        equipmentService.saveOrUpdate(factory, convertor.equipVOsToBeans(equips));
        // 3.1、检查项
        itemService.deleteByPointId(factory, pointId);
        itemService.saveOrUpdate(factory, items);
        // 3.2、数据记录项
        recordService.deleteByPointId(factory, pointId);
        recordService.saveOrUpdate(factory, records);
        return queryById(factory, pointId);
    }

    /**
     * 新增/编辑数据
     * @param factory
     * @param bean    实例对象
     * @return 实例对象
     */
    @Override
    public boolean saveOrUpdate(SessionFactory factory, PatrolPlanPointBean bean) {
        Assert.notNull(bean, "巡视点不能为空");
        PatrolPlanPointMapper mapper = factory.getMapper(PatrolPlanPointMapper.class);
        EamUser user = ThreadLocalContext.get();
        CommonUtils.update(bean);
        CommonUtils.update(bean, user.getId(), user.getName());
        bean.setId(StringUtils.isBlank(bean.getId()) ? CodeTools.getCode32() : bean.getId());
        bean.setCode(StringUtils.isBlank(bean.getCode()) ? CommonUtils.getCodeNo(Constants.PATROL_POINT_PREFIX, 3) : bean.getCode());
        bean.setDeptId(StringUtils.isBlank(bean.getDeptId()) ? user.getOrgId() : bean.getDeptId());
        bean.setPointDeptId(StringUtils.isBlank(bean.getPointDeptId()) ? user.getOrgId() : bean.getPointDeptId());
        bean.setPointDeptName(orgUtils.getOrgNameById(bean.getPointDeptId()));
        bean.setDeptName(orgUtils.getOrgNameById(bean.getDeptId()));
        return mapper.saveOrUpdate(bean) > 0;
    }

    /**
     * 通过巡视点id删除数据
     * @param pointId 巡视点id
     * @return 是否成功
     */
    @Override
    @TaskAnnotation("deleteById")
    public boolean deleteById(SessionFactory factory, String pointId) {
        return true;
    }

    /**
     * 通过巡视点id逻辑删除数据
     * @param pointId 巡视点id
     * @return 是否成功
     */
    @Override
    @TaskAnnotation("hiddenById")
    public boolean hiddenById(SessionFactory factory, String pointId) {
        PatrolPlanPointMapper mapper = factory.getMapper(PatrolPlanPointMapper.class);
        Assert.isTrue(mapper.countRefNum(pointId) <= 0, "已被使用的巡视点禁止删除");
        mapper.hiddenById(pointId);
        envService.hiddenByPointId(factory, pointId);
        equipmentService.hiddenByPointId(factory, pointId);
        itemService.hiddenByPointId(factory, pointId);
        recordService.hiddenByPointId(factory, pointId);
        return true;
    }
}
